package com.sea.physical.service.impl;

import com.codecrane.core.util.DateUtils;
import com.codecrane.core.util.PdfReadUtils;
import com.codecrane.core.web.BatchImportUtils;
import com.sea.physical.entity.CreateDistributeSku;
import com.sea.physical.entity.CreateSku;
import com.sea.physical.mapper.CreateDistributeSkuMapper;
import com.sea.physical.service.*;
import com.sea.product.entity.Product;
import com.sea.product.service.ProductService;
import com.sea.supply.entity.*;
import com.sea.supply.service.*;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.text.PDFTextStripper;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.Date;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

@Service
public class CreateDistributeSkuServiceImpl implements CreateDistributeSkuService {

    @Autowired
    private CreateDistributeSkuMapper createDistributeSkuMapper;
    @Autowired
    private ReceiveService receiveService;
    @Autowired
    private ProduceDetailService produceDetailService;
    @Autowired
    private CreateSkuService createSkuService;
    @Autowired
    private ProductService productService;
    @Autowired
    private CreateDistributeSkuService createDistributeSkuService;
    @Autowired
    private CreateDistributePlanService createDistributePlanService;
    @Autowired
    private CreatePlanService createPlanService;
    @Autowired
    private RecordService recordService;
    @Autowired
    private SupplierService supplierService;
    @Autowired
    private PdfService pdfService;
    @Autowired
    private WareDistributeService wareDistributeService;

    @Override
    public int save(CreateDistributeSku createDistributeSku) {

        return createDistributeSkuMapper.insert(createDistributeSku);
    }

    @Override
    public List<CreateDistributeSku> findByCreateId(Integer createId) {
        return createDistributeSkuMapper.findByCreateId(createId);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void importSku(InputStream inputStream, String fileName, Integer createId) throws Exception {
        Workbook workBook = BatchImportUtils.getWorkBook(inputStream,fileName);
        List<Sheet> sheets = BatchImportUtils.getSheets(workBook);
        if (null != sheets && sheets.size() > 0) {
            Sheet sheet = sheets.get(0);
            List<DistributeSku> skuList = BatchImportUtils.iteratorForDistributeSku(sheet);
            if(null==skuList||skuList.size()==0){
                throw new Exception("请至少新增一条明细！");
            }else{
                for(DistributeSku sku:skuList) {

                    String produceSupplierName = sku.getProduceSupplierName();
                    Supplier supplier = supplierService.findBySupplierName(produceSupplierName);
                    String supplierWare = supplier.getSupplierWare();
                    //
                    if (supplierWare.equals("否")) {
                        Integer receiveNumber = receiveService.getDistributeNumber(sku.getReceiveSku(), sku.getReceiveChannelName(), sku.getOrderDate(), sku.getReceiveNo());
                        //查询可分配数量
                        if (null == receiveNumber || receiveNumber == 0) {
                            throw new RuntimeException("【" + sku.getReceiveNo() + "-" + sku.getReceiveChannelName() + "-" + sku.getReceiveSku() + "-" + sku.getOrderDate() + "】可分配数量为0!");
                        } else {
                            Integer number = sku.getReceiveNumber();
                            if (receiveNumber - number < 0) {
                                throw new RuntimeException("【" + sku.getReceiveNo() + "-" + sku.getReceiveChannelName() + "-" + sku.getReceiveSku() + "-" + sku.getOrderDate() + "】超订单数据,请补足数量!");
                            }
                            //查询采购单明细
                            ProduceDetail produceDetail = produceDetailService.getIdByCnd(sku.getReceiveSku(), sku.getReceiveChannelName(), sku.getOrderDate(), sku.getReceiveNo());
                            //计算占有量
                            if(null==produceDetail){
                                throw new RuntimeException("【" + sku.getReceiveChannelName() + "-" + sku.getReceiveSku() + "】暂未查询到采购单明细!");
                            }
                            Integer useNumber = produceDetail.getProduceSurplus() - produceDetail.getProduceUse() - sku.getReceiveNumber();

                            //判断当前数据是否超占有
                            if (useNumber < 0) {
                                throw new RuntimeException("【" + sku.getReceiveNo() + "-" + sku.getReceiveChannelName() + "-" + sku.getReceiveSku() + "-" + sku.getOrderDate() + "】不能超出占有数量!");
                            }
                            //更新占有量
                            produceDetailService.updateUseNumber(produceDetail.getProduceUse() + sku.getReceiveNumber(), produceDetail.getId());
                            //新增分配数据
                            CreateSku createSku = createSkuService.findBySkuChannel(sku.getReceiveChannelName(), sku.getReceiveSku(), createId);
                            if (null == createSku) {
                                throw new RuntimeException("【" + sku.getReceiveChannelName() + "-" + sku.getReceiveSku() + "】暂未查询到发运明细!");
                            }
                            //新增分配明细
                            Product product = productService.findBySku(createSku.getCreateSku());
                            CreateDistributeSku createDistributeSku = new CreateDistributeSku();
                            createDistributeSku.setCreateId(createId);
                            createDistributeSku.setCreateSkuId(createSku.getId());
                            createDistributeSku.setCreateNumber(sku.getReceiveNumber());
                            createDistributeSku.setCreateBoxNumber((double) sku.getReceiveNumber() / (double) createSku.getCreatePackage());
                            createDistributeSku.setCreateNumberTotal(sku.getReceiveNumber() * product.getProductContainCount());
                            createDistributeSku.setCreateWeightTotal(createSku.getCreateWeight() * createDistributeSku.getCreateBoxNumber());
                            createDistributeSku.setCreateKgTotal(sku.getReceiveNumber() * product.getProductWeight());
                            createDistributeSku.setCreateVolumeTotal(createSku.getCreateVolume() * createDistributeSku.getCreateBoxNumber());
                            createDistributeSku.setCreateSupplierName(sku.getProduceSupplierName());
                            createDistributeSku.setErpProducePo(sku.getReceiveNo());
                            createDistributeSku.setErpProducePrice(produceDetail.getProducePriceCny());
                            createDistributeSku.setErpProduceUnitPrice(produceDetail.getProduceUnitPriceCny());
                            createDistributeSku.setCreateSupplierName(sku.getProduceSupplierName());
                            createDistributeSku.setCreateProduceId(produceDetail.getId());
                            createDistributeSkuService.save(createDistributeSku);
                        }
                    }else{
                        //如果是从国内仓走
                        WareProduce wareProduce=new WareProduce();
                        wareProduce.setProduceNo(sku.getReceiveNo());
                        wareProduce.setReceiveSku(sku.getReceiveSku());
                        wareProduce.setReceiveChannelName(sku.getReceiveChannelName());
                        wareProduce.setOrderDate(sku.getOrderDate());
                        WareDistribute receive = wareDistributeService.findReceiveNumber(wareProduce);
                        if (null == receive ) {
                            throw new RuntimeException("【" + sku.getReceiveNo() + "-" + sku.getReceiveChannelName() + "-" + sku.getReceiveSku() + "-" + sku.getOrderDate() + "】暂未查询到数据!");
                        }else{
                            Integer number = receive.getReceiveNumber() - receive.getProduceUse() - sku.getReceiveNumber();
                            if(number<0){
                                throw new RuntimeException("【" + sku.getReceiveNo() + "-" + sku.getReceiveChannelName() + "-" + sku.getReceiveSku() + "-" + sku.getOrderDate() + "】不能超出占有数量!");
                            }
                            //更新占有量
                            wareDistributeService.updateUseNumber(receive.getProduceUse() + sku.getReceiveNumber(), receive.getId());
                        }

                        //新增分配数据
                        CreateSku createSku = createSkuService.findBySkuChannel(sku.getReceiveChannelName(), sku.getReceiveSku(), createId);
                        if (null == createSku) {
                            throw new RuntimeException("【" + sku.getReceiveChannelName() + "-" + sku.getReceiveSku() + "】暂未查询到发运明细!");
                        }

                        ProduceDetail produceDetail = produceDetailService.getWareDistribute(sku.getReceiveSku(), sku.getReceiveChannelName(), sku.getOrderDate(), sku.getReceiveNo());
                        //新增分配明细
                        Product product = productService.findBySku(createSku.getCreateSku());
                        CreateDistributeSku createDistributeSku = new CreateDistributeSku();
                        createDistributeSku.setCreateId(createId);
                        createDistributeSku.setCreateSkuId(createSku.getId());
                        createDistributeSku.setCreateNumber(sku.getReceiveNumber());
                        createDistributeSku.setCreateBoxNumber((double) sku.getReceiveNumber() / (double) createSku.getCreatePackage());
                        createDistributeSku.setCreateNumberTotal(sku.getReceiveNumber() * product.getProductContainCount());
                        createDistributeSku.setCreateWeightTotal(createSku.getCreateWeight() * createDistributeSku.getCreateBoxNumber());
                        createDistributeSku.setCreateKgTotal(sku.getReceiveNumber() * product.getProductWeight());
                        createDistributeSku.setCreateVolumeTotal(createSku.getCreateVolume() * createDistributeSku.getCreateBoxNumber());
                        createDistributeSku.setErpProducePo(sku.getReceiveNo());
                        createDistributeSku.setErpProducePrice(produceDetail.getProducePriceCny());
                        createDistributeSku.setErpProduceUnitPrice(produceDetail.getProduceUnitPriceCny());
                        createDistributeSku.setCreateSupplierName(sku.getProduceSupplierName());
                        createDistributeSku.setCreateProduceId(receive.getId());
                        createDistributeSkuService.save(createDistributeSku);

                    }
                }

                createDistributePlanService.updateTotal(createId);
                //更新分配状态
                createPlanService.updateStatus(2,createId);
                //新增记录
                recordService.save(createId,2,"", DateUtils.dateToString(new Date()));
            }
        }
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void importAutoSku(InputStream inputStream, String fileName, Integer createId) throws Exception {
        Workbook workBook = BatchImportUtils.getWorkBook(inputStream,fileName);
        List<Sheet> sheets = BatchImportUtils.getSheets(workBook);
        if (null != sheets && sheets.size() > 0) {
            Sheet sheet = sheets.get(0);
            List<DistributeSku> createSkuList = BatchImportUtils.iteratorForAutoDistributeSku(sheet);
            if(null==createSkuList||createSkuList.size()==0){
                throw new Exception("请至少新增一条明细！");
            }else{
                for (DistributeSku distributeSku : createSkuList) {
                    List<Receive> produceDetailList =
                            receiveService.findByDistributeReadyUse(distributeSku.getReceiveSku(),
                                                                    distributeSku.getReceiveChannelName(),
                                                                    distributeSku.getOrderDate(),
                                                                    distributeSku.getProduceSupplierName(),
                                                                    distributeSku.getReceiveNo());
                    //取到需要分配的数量
                    Integer createNumber = distributeSku.getReceiveNumber();
                    for (Receive produceDetail : produceDetailList) {
                        CreateSku createSku = createSkuService.findBySkuChannel(distributeSku.getReceiveChannelName(), distributeSku.getReceiveSku(), createId);
                        Integer produceReadyUse = produceDetail.getProduceReadyUse();
                        //取到当前这一条可分配的最大数量
                        Integer totalNumber = produceDetail.getTotalNumber();
                        //如果可分配的数量 比计划数量多 则说明不用再循环下一条 更新预占有量
                        if (totalNumber >= createNumber) {
                            produceReadyUse = produceReadyUse + createNumber;
                            produceDetailService.updateReadyUseNumber(produceReadyUse, produceDetail.getId());
                            saveAutoDistributeSku(createNumber, createSku, produceDetail);
                            createNumber = 0;
                            break;
                        } else {
                            //扣掉当前分配的数量
                            createNumber = createNumber - totalNumber;
                            produceDetailService.updateReadyUseNumber(produceReadyUse + totalNumber, produceDetail.getId());
                            saveAutoDistributeSku(totalNumber, createSku, produceDetail);
                        }
                    }
                    //跑完判断是否还有计划数量
                    if (createNumber > 0) {
                        throw new RuntimeException("【" + distributeSku.getReceiveSku() + "-" + distributeSku.getReceiveChannelName() + "】超订单数据,请补足数量!");
                    }
                }
                createDistributePlanService.updateTotal(createId);
                //更新分配状态
                createPlanService.updateStatus(22, createId);
                //新增记录
                recordService.save(createId, 22, "", DateUtils.dateToString(new Date()));

                Integer dTotal = createDistributePlanService.findByCreateId(createId).getCreatePlanTotal();
                Integer pTotal = createPlanService.findById(createId).getCreatePlanTotal();
                if(!dTotal.equals(pTotal)){
                    throw new Exception("分配数量与计划数量不一致！");
                }
            }
        }
    }

    @Override
    public Integer deleteByCreateId(Integer createId) {
        return createDistributeSkuMapper.deleteByCreateId(createId);
    }

    @Override
    public CreateSku findByMonthChannelSku(String month, String channelName, String createSku) {
        return null;
    }

    @Override
    public List<CreateDistributeSku> getRows(Integer[] ids) {
        return createDistributeSkuMapper.getRows(ids);
    }

    @Override
    public CreateDistributeSku findByDetail(Integer createId, Integer createSkuId, Integer createProduceId, Integer createNumber) {
        return createDistributeSkuMapper.findByDetail(createId,createSkuId,createProduceId,createNumber);
    }

    @Override
    public Integer usave(CreateDistributeSku createDistributeSku) {
        return createDistributeSkuMapper.update(createDistributeSku);
    }

    @Override
    public List<CreateDistributeSku> findByCreateIdSupplier(Integer createId, String createSupplierName) {
        return createDistributeSkuMapper.findByCreateIdSupplier(createId,createSupplierName);
    }

    @Override
    public Integer updateQualityStatus(CreateDistributeSku createDistributeSku) {
        return createDistributeSkuMapper.updateQualityStatus(createDistributeSku);
    }

    @Override
    public Integer findQualityNumber(Integer id) {
        return createDistributeSkuMapper.findQualityNumber(id);
    }

    @Override
    public Integer updateCreatePlanNo() {
        return createDistributeSkuMapper.updateCreatePlanNo();
    }

    void saveAutoDistributeSku(Integer createNumber,CreateSku createSku,Receive produceDetail ) {
        Product product = productService.findBySku(createSku.getCreateSku());
        CreateDistributeSku createDistributeSku = new CreateDistributeSku();
        createDistributeSku.setCreateId(createSku.getCreateId());
        createDistributeSku.setCreateSkuId(createSku.getId());
        createDistributeSku.setCreateNumber(createNumber);
        createDistributeSku.setCreateBoxNumber((double) createNumber / (double) createSku.getCreatePackage());
        createDistributeSku.setCreateNumberTotal(createNumber * product.getProductContainCount());
        createDistributeSku.setCreateWeightTotal(createSku.getCreateWeight() * createDistributeSku.getCreateBoxNumber());
        createDistributeSku.setCreateKgTotal(createNumber * product.getProductWeight());
        createDistributeSku.setCreateVolumeTotal(createSku.getCreateVolume() * createDistributeSku.getCreateBoxNumber());
        createDistributeSku.setCreateSupplierName(produceDetail.getProduceSupplierName());
        createDistributeSku.setErpProducePo(produceDetail.getReceiveNo());
        createDistributeSku.setErpProducePrice(produceDetail.getProducePrice());
        createDistributeSku.setErpProduceUnitPrice(produceDetail.getProduceUnitPrice());
        createDistributeSku.setCreateSupplierName(produceDetail.getProduceSupplierName());
        createDistributeSku.setCreateProduceId(produceDetail.getId());
        createDistributeSkuService.save(createDistributeSku);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void autoDistribute(Integer createId) {
        List<CreateSku> createSkuList = createSkuService.findByCreateId(createId);
        for (CreateSku createSku : createSkuList) {

            if (createSku.getCreateSku().equals("ATO-SM4809")){
                System.out.println("1111");
            }
            if(createSku.getCreateChannelName().contains("Artecho")){
                //先看国内仓有没有数据
                distributeWareProduce(createSku);
//                throw new RuntimeException("判断国内仓");
            }else {
                distributeProduce(createSku);
            }
        }
        createDistributePlanService.updateTotal(createId);
        //更新分配状态
        createPlanService.updateStatus(22, createId);
        //新增记录
        recordService.save(createId, 22, "", DateUtils.dateToString(new Date()));
    }

    @Override
    public List<CreateDistributeSku> findTotalNumberByCreateId(Integer createId) {
        return createDistributeSkuMapper.findTotalNumberByCreateId(createId);
    }

    @Override
    public CreateDistributeSku findDetailById(Integer id) {
        return createDistributeSkuMapper.findDetailById(id);
    }

    @Override
    public List<CreateDistributeSku> findDistributeSkuBySupplierName(Integer createId) {
        return createDistributeSkuMapper.findDistributeSkuBySupplierName(createId);
    }

    @Override
    public List<CreateDistributeSku> findByCreateIdSupplierName(Integer createId, String createSupplierName) {
        return createDistributeSkuMapper.findByCreateIdSupplierName(createId,createSupplierName);
    }

    /**
     * 分配国内仓
     * @param createSku
     */
    @Transactional(rollbackFor = Exception.class)
    void distributeWareProduce(CreateSku createSku){
        List<WareDistribute> wareDistributeList =null ;

        if(createSku.getCreateChannelName().contains("artecho") || createSku.getCreateChannelName().contains("Artecho")){
            wareDistributeList = wareDistributeService.findByDistributeReadyUse(createSku.getCreateSku(),createSku.getCreateChannelName());
        }else {
            wareDistributeList = wareDistributeService.findByDistributeReadyUse(createSku.getCreateSku(), createSku.getCreateChannelName());
        }
        //取到需要分配的数量
        Integer createNumber = createSku.getCreateNumber();


        for (WareDistribute wareDistribute : wareDistributeList) {
            if(wareDistribute.getReceiveSku().equals("ATO-AP0084")){
                System.out.println("1111");

            }

            Integer produceReadyUse = wareDistribute.getProduceReadyUse();
            //取到当前这一条可分配的最大数量
            Integer totalNumber = wareDistribute.getReceiveNumber();
            //如果是海外仓去查采购单明细数据

            if(wareDistribute.getReceiveChannelName().contains("Artecho")){

            }else {

            }
            Receive produceDetail = receiveService.findByWareProduce(wareDistribute.getReceiveSku(), wareDistribute.getReceiveChannelName(), wareDistribute.getProduceNo());
            if(null==produceDetail){
                throw new RuntimeException("暂时无法获取到SKU信息【"+wareDistribute.getReceiveSku()+"】 PO【"+wareDistribute.getProduceNo()+"】");
            }
            produceDetail.setProduceSupplierName(wareDistribute.getWareName());
            //如果可分配的数量 比计划数量多 则说明不用再循环下一条 更新预占有量
            if (totalNumber >= createNumber) {
                produceReadyUse = produceReadyUse + createNumber;
                wareDistributeService.updateReadyUseNumber(produceReadyUse, wareDistribute.getId());
                saveAutoDistributeSku(createNumber, createSku, produceDetail);
                createNumber = 0;
                break;
            } else {
                //扣掉当前分配的数量
                createNumber = createNumber - totalNumber;
                wareDistributeService.updateReadyUseNumber(produceReadyUse + totalNumber, wareDistribute.getId());
                saveAutoDistributeSku(totalNumber, createSku, produceDetail);
            }
        }
        //跑完判断是否还有计划数量 继续跑
        if (createNumber > 0) {
            createSku.setCreateNumber(createNumber);
            distributeProduce(createSku);
        }
    }

    /**
     * 分配供应商
     * @param createSku
     */
    @Transactional(rollbackFor = Exception.class)
    void distributeProduce(CreateSku createSku){

        List<Receive> produceDetailList = receiveService.findByDistributeReadyUse(createSku.getCreateSku(), createSku.getCreateChannelName(),null,null,null);
        //取到需要分配的数量
        Integer createNumber = createSku.getCreateNumber();
        for (Receive produceDetail : produceDetailList) {
            Integer produceReadyUse = produceDetail.getProduceReadyUse();
            //取到当前这一条可分配的最大数量
            Integer totalNumber = produceDetail.getTotalNumber();
            //如果可分配的数量 比计划数量多 则说明不用再循环下一条 更新预占有量
            if (totalNumber >= createNumber) {
                produceReadyUse = produceReadyUse + createNumber;
                produceDetailService.updateReadyUseNumber(produceReadyUse, produceDetail.getId());
                saveAutoDistributeSku(createNumber, createSku, produceDetail);
                createNumber = 0;
                break;
            } else {
                //扣掉当前分配的数量
                createNumber = createNumber - totalNumber;
                produceDetailService.updateReadyUseNumber(produceReadyUse + totalNumber, produceDetail.getId());
                saveAutoDistributeSku(totalNumber, createSku, produceDetail);
            }
        }
        //跑完判断是否还有计划数量
        if (createNumber > 0) {
            throw new RuntimeException("【" + createSku.getCreateSku() + "-" + createSku.getCreateChannelName() + "】超订单数据,请补足数量!");
        }
    }
}
